import java.io.*;
import java.util.*;
import java.sql.*;

public class DTNMessageManager{
	private MessageStatistics messages;
	private double threshold;
	//private DTNJDBCConnector conn;

	private void Report(String message){
		System.out.println(message);
	}
	
	public DTNMessageManager(MessageStatistics messages, double threshold){
		this.messages = messages;
		this.threshold = threshold;
		//this.conn = new DTNJDBCConnector();
	}
	//For all of the report functions, NodeID is the NodeID of the node that called the function.
	public boolean reportDeliveredMessages(String NodeID){
		
		//System.out.println("Reporting any delivered messages");
		DTNJDBCConnector conn = new DTNJDBCConnector();
		ArrayList<String> messages2 = messages.deliverMessages(NodeID);
		String source;
		String destination;
		int sequence;
		int TTL;
		String sql;
		sql = "INSERT INTO DELIVERED_MESSAGE_RPT (RPT_SK, SOURCE, DESTINATION, MESSAGE_ID, TIME_TO_LIVE, THRESHOLD)"
				+ " VALUES (RPT_SEQ.NEXTVAL, ?, ?, ?, ?, ?)";
		PreparedStatement stmt = conn.createConnection(sql);
		Scanner messageParser;
		for(int x = 0 ; x < messages2.size(); x++) { 
			messageParser = new Scanner(messages2.get(x));
			messageParser.useDelimiter(";");
			if (messageParser.hasNext()){
				source = messageParser.next();
				if (messageParser.hasNext()){
					destination = messageParser.next();
					if (messageParser.hasNextInt()){
						sequence = messageParser.nextInt();
						if (messageParser.hasNextInt()){
							TTL = messageParser.nextInt();
							//put in the database
							try {
								stmt.setString(1, source);
								stmt.setString(2, destination);
								stmt.setInt(3, sequence);
								stmt.setInt(4, TTL);
								stmt.setDouble(5, threshold);
								stmt.executeUpdate();
								//System.out.println("Delivered a message");
							}
							catch (SQLException e)
							{
								e.printStackTrace();
							}
							//System.out.println ("Source: " + source + " " + "Destination: " + destination + "seq: " + sequence + "TTL: " + TTL);
						}
					}
				}
			}
			messageParser.close();
		}
		//if (mailline.getMessageDestination(NodeID) = destination) {
		//}
		//one per line string
		//call deliverMessages(nodeid);
		//called at the end of a communication session.
		//This should make a record of all messages where getMessageDestination(messageID) = NodeID
		try{
			if(stmt != null)
				stmt.close();
			conn.release();
		} catch (Exception e){

		}

		 
		if (messages2.size() > 0)
			Report("Delivered " + messages2.size() + " messages to " + NodeID);
		return true;
	}
	public boolean reportUndeliveredMessages(String NodeID){
		
		DTNJDBCConnector conn = new DTNJDBCConnector();

		ArrayList<String> messages2 = messages.removeDeadMessages();
		String source;
		String destination;
		int sequence;
		int TTL;
		String sql;
		sql = "INSERT INTO UNDELIVERED_MESSAGE_RPT (RPT_SK, SOURCE, DESTINATION, MESSAGE_ID, THRESHOLD)"
				+ " VALUES (RPT_SEQ.NEXTVAL, ?, ?, ?, ?)";
		PreparedStatement stmt = conn.createConnection(sql);
		Scanner messageParser;
		for(int x = 0 ; x < messages2.size(); x++) { 
			messageParser = new Scanner(messages2.get(x));
			messageParser.useDelimiter(";");
			if (messageParser.hasNext()){
				source = messageParser.next();
				if (messageParser.hasNext()){
					destination = messageParser.next();
					if (messageParser.hasNextInt()){
						sequence = messageParser.nextInt();
						if (messageParser.hasNextInt()){
							TTL = messageParser.nextInt();
							//put it in the database
							try {
								stmt.setString(1, source);
								stmt.setString(2, destination);
								stmt.setInt(3, sequence);
								stmt.setDouble(4, threshold);
								stmt.executeUpdate();
								//System.out.println("Couldn't deliver a message");
							}
							catch (SQLException e)
							{
								e.printStackTrace();
							}
							//System.out.println ("Source: " + source + " " + "Destination: " + destination + "seq: " + sequence + "TTL: " + TTL);
						}
					}
				}
			}
			messageParser.close();
		}
		//removeDeadmessages
		//called at the end of a communication session.
		//This should make a record of all messages where getMessageTTL(messageID) <= 0
		try{
			if(stmt != null)
				stmt.close();
			conn.release();
		} catch (Exception e){

		}

		if (messages2.size() > 0)
			Report(messages2.size() + " undeliverable messages at " + NodeID);
		return true;
	}
	public boolean reportPropagationType(String NodeID, String partnerNodeID, int type){
		//called at the end of a communication session.
		//This should report which type of communication was used, given by the type
		//parameter. 1=Prophet, 2=ERP
		
		DTNJDBCConnector conn = new DTNJDBCConnector();
		

		String sql;

		sql = "INSERT INTO PROPAGATION_TYPE_RPT (RPT_SK, NODE1, NODE2, STAT_TYPE, THRESHOLD)"
				+ " VALUES (RPT_SEQ.NEXTVAL, ?, ?, ?, ?)";

		PreparedStatement stmt = conn.createConnection(sql);

		try {
			stmt.setString(1,NodeID);
			stmt.setString(2, partnerNodeID);
			stmt.setInt(3, type);
			stmt.setDouble(4, threshold);
			stmt.executeUpdate();
		}
		catch (Exception e)
		{
			//e.printStackTrace();
		}

		//called at the end of a communication session.
		//This should report which type of communication was used, given by the type
		//parameter. 1=Prophet, 2=ERP
		try {
			if(stmt != null) {
				stmt.close();
			}
			conn.release();
		}
		catch (Exception e)
		{
			//e.printStackTrace();
		}
		
		
		return true;
	}
	public boolean reportMessageBuffer(String NodeID){
		
		int messagecount = messages.messageCount();
		

		DTNJDBCConnector conn = new DTNJDBCConnector();		

		String sql;

		sql = "INSERT INTO MESSAGE_BUFFER_RPT (RPT_SK, NODEID, MESSAGE_COUNT, THRESHOLD)"
				+ " VALUES (RPT_SEQ.NEXTVAL, ?, ?, ?)";

		PreparedStatement stmt = conn.createConnection(sql);

		try {
			stmt.setString(1, NodeID);
			stmt.setInt(2, messagecount);
			stmt.setDouble(3, threshold);
			stmt.executeUpdate();
		}
		catch (Exception e)
		{
			//e.printStackTrace();
		}


		//messageCount()
		//called at the end of a communication session.
		//This should report the total number of messages currently in the buffer.
		try {
			if(stmt != null) {
				stmt.close();
			}
			conn.release();
		}
		catch (Exception e)
		{
			//e.printStackTrace();
		}
		
		return true;
	}
}